package org.alwayssuper.protocol.commons.transform.realtimev2016;

import org.alwayssuper.protostar.annotation.Field;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

/**
 * 2016版整车数据格式 (0x01)
 * 参考AICoding报文规则文档
 * @author alwaysSuper
 */
@ToString
@Data
@Accessors(chain = true)
public class Vehicle {
    @Field(length = 1, desc = "车辆状态:0x01:启动;0x02:熄火;0x03:其他;0xFE:异常;0xFF:无效")
    private int vehicleStatus;
    
    @Field(length = 1, desc = "充电状态:0x01:停车充电;0x02:行驶充电;0x03:未充电;0x04:充电完成;0xFE:异常;0xFF:无效")
    private int chargingStatus;
    
    @Field(length = 1, desc = "运行模式:0x01:纯电;0x02:混动;0x03:燃油;0xFE:异常;0xFF:无效")
    private int operationMode;
    
    @Field(length = 2, desc = "车速:0~220km/h,精度0.1km/h,0xFFFF无效")
    private int speed;
    
    @Field(length = 4, desc = "累计里程:0~999999.9km,精度0.1km,0xFFFFFFFF无效")
    private int odometer;
    
    @Field(length = 2, desc = "总电压:0~1000V,精度0.1V,0xFFFF无效")
    private int totalVoltage;
    
    @Field(length = 2, desc = "总电流:-1000A~+1000A,精度0.1A,偏移1000A,0xFFFF无效")
    private int totalCurrent;
    
    @Field(length = 1, desc = "SOC:0~100%,精度1%,0xFF无效")
    private int soc;
    
    @Field(length = 1, desc = "DC-DC状态:0x01:工作;0x02:断开;0xFE:异常;0xFF:无效")
    private int dcDcStatus;
    
    @Field(length = 1, desc = "挡位:bit0-3:挡位值;bit4:停车挡;bit5:倒车挡;bit6:空挡;bit7:前进挡;0xFF:无效")
    private int gearPosition;
    
    @Field(length = 2, desc = "绝缘电阻:0~60000kΩ,精度1kΩ,0xFFFF无效")
    private int insulationResistance;
    
    @Field(length = 2, desc = "预留")
    private int reserved;
    
    // =========================== 传输值与真实值转换方法 ===========================
    
    /**
     * 获取车速值 (km/h)
     * 传输值范围: 0~2200, 表示 0~220.0 km/h, 精度 0.1 km/h
     * 0xFFFE: 异常, 0xFFFF: 无效
     */
    public double getSpeed() {
        if (speed == 0xFFFE || speed == 0xFFFF) {
            return Double.NaN;
        }
        return speed * 0.1;
    }
    
    /**
     * 设置车速值 (km/h)
     * 值范围: 0.0~220.0 km/h
     */
    public void setSpeed(double speed) {
        if (Double.isNaN(speed) || speed < 0 || speed > 220.0) {
            this.speed = 0xFFFF; // 无效
        } else {
            this.speed = (int) Math.round(speed * 10);
        }
    }
    
    /**
     * 获取累计里程值 (km)
     * 传输值范围: 0~9999999, 表示 0~999999.9 km, 精度 0.1 km
     * 0xFFFFFFFE: 异常, 0xFFFFFFFF: 无效
     */
    public double getOdometer() {
        if (odometer == 0xFFFFFFFEL || odometer == 0xFFFFFFFFL) {
            return Double.NaN;
        }
        return odometer * 0.1;
    }
    
    /**
     * 设置累计里程值 (km)
     * 值范围: 0.0~999999.9 km
     */
    public void setOdometer(double odometer) {
        if (Double.isNaN(odometer) || odometer < 0 || odometer > 999999.9) {
            this.odometer = 0xFFFFFFFF; // 无效
        } else {
            this.odometer = (int) Math.round(odometer * 10);
        }
    }
    
    /**
     * 获取总电压值 (V)
     * 传输值范围: 0~10000, 表示 0~1000.0 V, 精度 0.1 V
     * 0xFFFE: 异常, 0xFFFF: 无效
     */
    public double getTotalVoltage() {
        if (totalVoltage == 0xFFFE || totalVoltage == 0xFFFF) {
            return Double.NaN;
        }
        return totalVoltage * 0.1;
    }
    
    /**
     * 设置总电压值 (V)
     * 值范围: 0.0~1000.0 V
     */
    public void setTotalVoltage(double totalVoltage) {
        if (Double.isNaN(totalVoltage) || totalVoltage < 0 || totalVoltage > 1000.0) {
            this.totalVoltage = 0xFFFF; // 无效
        } else {
            this.totalVoltage = (int) Math.round(totalVoltage * 10);
        }
    }
    
    /**
     * 获取总电流值 (A)
     * 传输值范围: 0~20000, 偏移量1000A, 表示 -1000.0A~+1000.0A, 精度 0.1A
     * 0xFFFE: 异常, 0xFFFF: 无效
     */
    public double getTotalCurrent() {
        if (totalCurrent == 0xFFFE || totalCurrent == 0xFFFF) {
            return Double.NaN;
        }
        return (totalCurrent - 10000) * 0.1;
    }
    
    /**
     * 设置总电流值 (A)
     * 值范围: -1000.0A~+1000.0A
     */
    public void setTotalCurrent(double totalCurrent) {
        if (Double.isNaN(totalCurrent) || totalCurrent < -1000.0 || totalCurrent > 1000.0) {
            this.totalCurrent = 0xFFFF; // 无效
        } else {
            this.totalCurrent = (int) Math.round(totalCurrent * 10 + 10000);
        }
    }
    
    /**
     * 获取SOC值 (%)
     * 传输值范围: 0~100, 表示 0%~100%, 精度 1%
     * 0xFE: 异常, 0xFF: 无效
     */
    public double getSoc() {
        if (soc == 0xFE || soc == 0xFF) {
            return Double.NaN;
        }
        return soc;
    }
    
    /**
     * 设置SOC值 (%)
     * 值范围: 0%~100%
     */
    public void setSoc(double soc) {
        if (Double.isNaN(soc) || soc < 0 || soc > 100) {
            this.soc = 0xFF; // 无效
        } else {
            this.soc = (int) Math.round(soc);
        }
    }
    
    /**
     * 获取绝缘电阻值 (kΩ)
     * 传输值范围: 0~60000, 表示 0~60000 kΩ, 精度 1 kΩ
     * 0xFFFE: 异常, 0xFFFF: 无效
     */
    public double getInsulationResistance() {
        if (insulationResistance == 0xFFFE || insulationResistance == 0xFFFF) {
            return Double.NaN;
        }
        return insulationResistance;
    }
    
    /**
     * 设置绝缘电阻值 (kΩ)
     * 值范围: 0~60000 kΩ
     */
    public void setInsulationResistance(double insulationResistance) {
        if (Double.isNaN(insulationResistance) || insulationResistance < 0 || insulationResistance > 60000) {
            this.insulationResistance = 0xFFFF; // 无效
        } else {
            this.insulationResistance = (int) Math.round(insulationResistance);
        }
    }
    
    /**
     * 检查车速是否异常
     */
    public boolean isSpeedAbnormal() {
        return speed == 0xFFFE;
    }
    
    /**
     * 检查车速是否无效
     */
    public boolean isSpeedInvalid() {
        return speed == 0xFFFF;
    }
    
    /**
     * 检查总电压是否异常
     */
    public boolean isTotalVoltageAbnormal() {
        return totalVoltage == 0xFFFE;
    }
    
    /**
     * 检查总电压是否无效
     */
    public boolean isTotalVoltageInvalid() {
        return totalVoltage == 0xFFFF;
    }
    
    /**
     * 检查总电流是否异常
     */
    public boolean isTotalCurrentAbnormal() {
        return totalCurrent == 0xFFFE;
    }
    
    /**
     * 检查总电流是否无效
     */
    public boolean isTotalCurrentInvalid() {
        return totalCurrent == 0xFFFF;
    }
    
    /**
     * 检查SOC是否异常
     */
    public boolean isSocAbnormal() {
        return soc == 0xFE;
    }
    
    /**
     * 检查SOC是否无效
     */
    public boolean isSocInvalid() {
        return soc == 0xFF;
    }
}